home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / points.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  15.3 KB  |  554 lines

  1. /* $Id: points.c,v 1.6 1997/03/08 02:04:27 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: points.c,v $
  26.  * Revision 1.6  1997/03/08 02:04:27  brianp
  27.  * better implementation of feedback function
  28.  *
  29.  * Revision 1.5  1997/02/09 18:43:52  brianp
  30.  * added GL_EXT_texture3D support
  31.  *
  32.  * Revision 1.4  1997/01/09 19:48:00  brianp
  33.  * now call gl_texturing_enabled()
  34.  *
  35.  * Revision 1.3  1996/11/08 02:21:21  brianp
  36.  * added null drawing function for GL_NO_RASTER
  37.  *
  38.  * Revision 1.2  1996/09/15 14:18:37  brianp
  39.  * now use GLframebuffer and GLvisual
  40.  *
  41.  * Revision 1.1  1996/09/13 01:38:16  brianp
  42.  * Initial revision
  43.  *
  44.  */
  45.  
  46.  
  47. #include "context.h"
  48. #include "feedback.h"
  49. #include "dlist.h"
  50. #include "macros.h"
  51. #include "pb.h"
  52. #include "span.h"
  53. #include "texture.h"
  54. #include "types.h"
  55. #include "vb.h"
  56.  
  57.  
  58.  
  59.  
  60. void gl_PointSize( GLcontext *ctx, GLfloat size )
  61. {
  62.    if (size<=0.0) {
  63.       gl_error( ctx, GL_INVALID_VALUE, "glPointSize" );
  64.       return;
  65.    }
  66.    if (INSIDE_BEGIN_END(ctx)) {
  67.       gl_error( ctx, GL_INVALID_OPERATION, "glPointSize" );
  68.       return;
  69.    }
  70.    ctx->Point.Size = size;
  71.    ctx->NewState |= NEW_RASTER_OPS;
  72. }
  73.  
  74.  
  75.  
  76. /**********************************************************************/
  77. /*****                    Rasterization                           *****/
  78. /**********************************************************************/
  79.  
  80.  
  81. /*
  82.  * There are 3 pairs (RGBA, CI) of point rendering functions:
  83.  *   1. simple:  size=1 and no special rasterization functions (fastest)
  84.  *   2. size1:  size=1 and any rasterization functions
  85.  *   3. general:  any size and rasterization functions (slowest)
  86.  *
  87.  * All point rendering functions take the same two arguments: first and
  88.  * last which specify that the points specified by VB[first] through
  89.  * VB[last] are to be rendered.
  90.  */
  91.  
  92.  
  93.  
  94. /*
  95.  * Put points in feedback buffer.
  96.  */
  97. static void feedback_points( GLcontext *ctx, GLuint first, GLuint last )
  98. {
  99.    struct vertex_buffer *VB = ctx->VB;
  100.    GLuint i;
  101.    GLfloat invRedScale   = ctx->Visual->InvRedScale;
  102.    GLfloat invGreenScale = ctx->Visual->InvGreenScale;
  103.    GLfloat invBlueScale  = ctx->Visual->InvBlueScale;
  104.    GLfloat invAlphaScale = ctx->Visual->InvAlphaScale;
  105.  
  106.    for (i=first;i<=last;i++) {
  107.       if (VB->Unclipped[i]) {
  108.          GLfloat x, y, z, w, invq;
  109.          GLfloat color[4], texcoord[4];
  110.  
  111.          x = VB->Win[i][0];
  112.          y = VB->Win[i][1];
  113.          z = VB->Win[i][2] / DEPTH_SCALE;
  114.          w = VB->Clip[i][3];
  115.  
  116.          /* convert color from integer back to a float in [0,1] */
  117.          if (ctx->Light.ShadeModel==GL_SMOOTH) {
  118.             /* smooth shading - colors are in fixed point */
  119.             color[0] = FixedToFloat(VB->Color[i][0]) * invRedScale;
  120.             color[1] = FixedToFloat(VB->Color[i][1]) * invGreenScale;
  121.             color[2] = FixedToFloat(VB->Color[i][2]) * invBlueScale;
  122.             color[3] = FixedToFloat(VB->Color[i][3]) * invAlphaScale;
  123.          }
  124.          else {
  125.             /* flat shading - colors are integers */
  126.             color[0] = VB->Color[i][0] * invRedScale;
  127.             color[1] = VB->Color[i][1] * invGreenScale;
  128.             color[2] = VB->Color[i][2] * invBlueScale;
  129.             color[3] = VB->Color[i][3] * invAlphaScale;
  130.          }
  131.          invq = 1.0F / VB->TexCoord[i][3];
  132.          texcoord[0] = VB->TexCoord[i][0] * invq;
  133.          texcoord[1] = VB->TexCoord[i][1] * invq;
  134.          texcoord[2] = VB->TexCoord[i][2] * invq;
  135.          texcoord[3] = VB->TexCoord[i][3];
  136.  
  137.          FEEDBACK_TOKEN( ctx, (GLfloat) GL_POINT_TOKEN );
  138.          gl_feedback_vertex( ctx, x, y, z, w, color,
  139.                              (GLfloat) VB->Index[i], texcoord );
  140.       }
  141.    }
  142. }
  143.  
  144.  
  145.  
  146. /*
  147.  * Put points in selection buffer.
  148.  */
  149. static void select_points( GLcontext *ctx, GLuint first, GLuint last )
  150. {
  151.    struct vertex_buffer *VB = ctx->VB;
  152.    GLuint i;
  153.  
  154.    for (i=first;i<=last;i++) {
  155.       if (VB->Unclipped[i]) {
  156.          gl_update_hitflag( ctx, VB->Win[i][2] / DEPTH_SCALE );
  157.       }
  158.    }
  159. }
  160.  
  161.  
  162. /*
  163.  * CI points with size == 1.0
  164.  */
  165. void size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
  166. {
  167.    struct vertex_buffer *VB = ctx->VB;
  168.    struct pixel_buffer *PB = ctx->PB;
  169.    GLfloat *win;
  170.    GLint *pbx = PB->x, *pby = PB->y;
  171.    GLdepth *pbz = PB->z;
  172.    GLuint *pbi = PB->i;
  173.    GLuint pbcount = PB->count;
  174.    GLuint i;
  175.  
  176.    win = &VB->Win[first][0];
  177.    for (i=first;i<=last;i++) {
  178.       if (VB->Unclipped[i]) {
  179.          pbx[pbcount] = (GLint)  win[0];
  180.          pby[pbcount] = (GLint)  win[1];
  181.          pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
  182.          pbi[pbcount] = VB->Index[i];
  183.          pbcount++;
  184.       }
  185.       win += 3;
  186.    }
  187.    PB->count = pbcount;
  188.    PB_CHECK_FLUSH(ctx, PB)
  189. }
  190.  
  191.  
  192.  
  193. /*
  194.  * RGBA points with size == 1.0
  195.  */
  196. static void size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  197. {
  198.    struct vertex_buffer *VB = ctx->VB;
  199.    struct pixel_buffer *PB = ctx->PB;
  200.    GLuint i;
  201.    GLint shift = ctx->ColorShift;
  202.  
  203.    for (i=first;i<=last;i++) {
  204.       if (VB->Unclipped[i]) {
  205.          GLint x, y, z;
  206.          GLint red, green, blue, alpha;
  207.  
  208.          x = (GLint)  VB->Win[i][0];
  209.          y = (GLint)  VB->Win[i][1];
  210.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  211.  
  212.          red   = VB->Color[i][0] >> shift;
  213.          green = VB->Color[i][1] >> shift;
  214.          blue  = VB->Color[i][2] >> shift;
  215.          alpha = VB->Color[i][3] >> shift;
  216.  
  217.          PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
  218.       }
  219.    }
  220.    PB_CHECK_FLUSH(ctx,PB)
  221. }
  222.  
  223.  
  224.  
  225. /*
  226.  * General CI points.
  227.  */
  228. static void general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
  229. {
  230.    struct vertex_buffer *VB = ctx->VB;
  231.    struct pixel_buffer *PB = ctx->PB;
  232.    GLuint i;
  233.    GLint isize;
  234.  
  235.    isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  236.  
  237.    for (i=first;i<=last;i++) {
  238.       if (VB->Unclipped[i]) {
  239.          GLint x, y, z;
  240.          GLint x0, x1, y0, y1;
  241.          GLint ix, iy;
  242.  
  243.          x = (GLint)  VB->Win[i][0];
  244.          y = (GLint)  VB->Win[i][1];
  245.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  246.  
  247.          if (isize&1) {
  248.             /* odd size */
  249.             x0 = x - isize/2;
  250.             x1 = x + isize/2;
  251.             y0 = y - isize/2;
  252.             y1 = y + isize/2;
  253.          }
  254.          else {
  255.             /* even size */
  256.             x0 = (GLint) (x + 0.5F) - isize/2;
  257.             x1 = x0 + isize-1;
  258.             y0 = (GLint) (y + 0.5F) - isize/2;
  259.             y1 = y0 + isize-1;
  260.          }
  261.  
  262.          PB_SET_INDEX( ctx, PB, VB->Index[i] );
  263.  
  264.          for (iy=y0;iy<=y1;iy++) {
  265.             for (ix=x0;ix<=x1;ix++) {
  266.                PB_WRITE_PIXEL( PB, ix, iy, z );
  267.             }
  268.          }
  269.          PB_CHECK_FLUSH(ctx,PB)
  270.       }
  271.    }
  272. }
  273.  
  274.  
  275. /*
  276.  * General RGBA points.
  277.  */
  278. static void general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  279. {
  280.    struct vertex_buffer *VB = ctx->VB;
  281.    struct pixel_buffer *PB = ctx->PB;
  282.    GLuint i;
  283.    GLint isize;
  284.    GLint shift = ctx->ColorShift;
  285.  
  286.    isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  287.  
  288.    for (i=first;i<=last;i++) {
  289.       if (VB->Unclipped[i]) {
  290.          GLint x, y, z;
  291.          GLint x0, x1, y0, y1;
  292.          GLint ix, iy;
  293.  
  294.          x = (GLint)  VB->Win[i][0];
  295.          y = (GLint)  VB->Win[i][1];
  296.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  297.  
  298.          if (isize&1) {
  299.             /* odd size */
  300.             x0 = x - isize/2;
  301.             x1 = x + isize/2;
  302.             y0 = y - isize/2;
  303.             y1 = y + isize/2;
  304.          }
  305.          else {
  306.             /* even size */
  307.             x0 = (GLint) (x + 0.5F) - isize/2;
  308.             x1 = x0 + isize-1;
  309.             y0 = (GLint) (y + 0.5F) - isize/2;
  310.             y1 = y0 + isize-1;
  311.          }
  312.  
  313.          PB_SET_COLOR( ctx, PB,
  314.                        VB->Color[i][0] >> shift,
  315.                        VB->Color[i][1] >> shift,
  316.                        VB->Color[i][2] >> shift,
  317.                        VB->Color[i][3] >> shift );
  318.  
  319.          for (iy=y0;iy<=y1;iy++) {
  320.             for (ix=x0;ix<=x1;ix++) {
  321.                PB_WRITE_PIXEL( PB, ix, iy, z );
  322.             }
  323.          }
  324.          PB_CHECK_FLUSH(ctx,PB)
  325.       }
  326.    }
  327. }
  328.  
  329.  
  330.  
  331.  
  332. /*
  333.  * Textured RGBA points.
  334.  */
  335. static void textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  336. {
  337.    struct vertex_buffer *VB = ctx->VB;
  338.    struct pixel_buffer *PB = ctx->PB;
  339.    GLuint i;
  340.    GLint shift = ctx->ColorShift;
  341.  
  342.    for (i=first;i<=last;i++) {
  343.       if (VB->Unclipped[i]) {
  344.          GLint x, y, z;
  345.          GLint x0, x1, y0, y1;
  346.          GLint ix, iy;
  347.          GLint isize;
  348.          GLint red, green, blue, alpha;
  349.          GLfloat s, t, u;
  350.  
  351.          x = (GLint)  VB->Win[i][0];
  352.          y = (GLint)  VB->Win[i][1];
  353.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  354.  
  355.          isize = (GLint)
  356.                    (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  357.          if (isize<1) {
  358.             isize = 1;
  359.          }
  360.  
  361.          if (isize&1) {
  362.             /* odd size */
  363.             x0 = x - isize/2;
  364.             x1 = x + isize/2;
  365.             y0 = y - isize/2;
  366.             y1 = y + isize/2;
  367.          }
  368.          else {
  369.             /* even size */
  370.             x0 = (GLint) (x + 0.5F) - isize/2;
  371.             x1 = x0 + isize-1;
  372.             y0 = (GLint) (y + 0.5F) - isize/2;
  373.             y1 = y0 + isize-1;
  374.          }
  375.  
  376.          red   = VB->Color[i][0] >> shift;
  377.          green = VB->Color[i][1] >> shift;
  378.          blue  = VB->Color[i][2] >> shift;
  379.          alpha = VB->Color[i][3] >> shift;
  380.          s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  381.          t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  382.          u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  383.  
  384. /*    don't think this is needed
  385.          PB_SET_COLOR( red, green, blue, alpha );
  386. */
  387.  
  388.          for (iy=y0;iy<=y1;iy++) {
  389.             for (ix=x0;ix<=x1;ix++) {
  390.                PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u );
  391.             }
  392.          }
  393.          PB_CHECK_FLUSH(ctx,PB)
  394.       }
  395.    }
  396. }
  397.  
  398.  
  399.  
  400. /*
  401.  * Antialiased points with or without texture mapping.
  402.  */
  403. static void antialiased_rgba_points( GLcontext *ctx,
  404.                                      GLuint first, GLuint last )
  405. {
  406.    struct vertex_buffer *VB = ctx->VB;
  407.    struct pixel_buffer *PB = ctx->PB;
  408.    GLuint i;
  409.    GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
  410.    GLint shift = ctx->ColorShift;
  411.  
  412.    radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
  413.    rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  414.    rmax = radius + 0.7071F;
  415.    rmin2 = rmin*rmin;
  416.    rmax2 = rmax*rmax;
  417.    cscale = 256.0F / (rmax2-rmin2);
  418.  
  419.    if (gl_texturing_enabled(ctx)) {
  420.       for (i=first;i<=last;i++) {
  421.          if (VB->Unclipped[i]) {
  422.             GLint xmin, ymin, xmax, ymax;
  423.             GLint x, y, z;
  424.             GLint red, green, blue, alpha;
  425.             GLfloat s, t, u;
  426.  
  427.             xmin = (GLint) (VB->Win[i][0] - radius);
  428.             xmax = (GLint) (VB->Win[i][0] + radius);
  429.             ymin = (GLint) (VB->Win[i][1] - radius);
  430.             ymax = (GLint) (VB->Win[i][1] + radius);
  431.             z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  432.  
  433.             red   = VB->Color[i][0] >> shift;
  434.             green = VB->Color[i][1] >> shift;
  435.             blue  = VB->Color[i][2] >> shift;
  436.             s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  437.             t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  438.             u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  439.  
  440.             for (y=ymin;y<=ymax;y++) {
  441.                for (x=xmin;x<=xmax;x++) {
  442.                   GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  443.                   GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  444.                   GLfloat dist2 = dx*dx + dy*dy;
  445.                   if (dist2<rmax2) {
  446.                      alpha = VB->Color[i][3] >> shift;
  447.                      if (dist2>=rmin2) {
  448.                         GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  449.                         /* coverage is in [0,256] */
  450.                         alpha = (alpha * coverage) >> 8;
  451.                      }
  452.                      PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s, t, u );
  453.                   }
  454.                }
  455.             }
  456.             PB_CHECK_FLUSH(ctx,PB)
  457.          }
  458.       }
  459.    }
  460.    else {
  461.       /* Not texture mapped */
  462.       for (i=first;i<=last;i++) {
  463.          if (VB->Unclipped[i]) {
  464.             GLint xmin, ymin, xmax, ymax;
  465.             GLint x, y, z;
  466.             GLint red, green, blue, alpha;
  467.  
  468.             xmin = (GLint) (VB->Win[i][0] - radius);
  469.             xmax = (GLint) (VB->Win[i][0] + radius);
  470.             ymin = (GLint) (VB->Win[i][1] - radius);
  471.             ymax = (GLint) (VB->Win[i][1] + radius);
  472.             z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  473.  
  474.             red   = VB->Color[i][0] >> shift;
  475.             green = VB->Color[i][1] >> shift;
  476.             blue  = VB->Color[i][2] >> shift;
  477.  
  478.             for (y=ymin;y<=ymax;y++) {
  479.                for (x=xmin;x<=xmax;x++) {
  480.                   GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  481.                   GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  482.                   GLfloat dist2 = dx*dx + dy*dy;
  483.                   if (dist2<rmax2) {
  484.                      alpha = VB->Color[i][3] >> shift;
  485.                      if (dist2>=rmin2) {
  486.                         GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  487.                         /* coverage is in [0,256] */
  488.                         alpha = (alpha * coverage) >> 8;
  489.                      }
  490.                      PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
  491.                   }
  492.                }
  493.             }
  494.             PB_CHECK_FLUSH(ctx,PB)
  495.          }
  496.       }
  497.    }
  498. }
  499.  
  500.  
  501.  
  502. /*
  503.  * Null rasterizer for measuring transformation speed.
  504.  */
  505. static void null_points( GLcontext *ctx, GLuint first, GLuint last )
  506. {
  507. }
  508.  
  509.  
  510.  
  511. /*
  512.  * Examine the current context to determine which point drawing function
  513.  * should be used.
  514.  */
  515. void gl_set_point_function( GLcontext *ctx )
  516. {
  517.    GLboolean rgbmode = ctx->Visual->RGBAflag;
  518.  
  519.    if (ctx->RenderMode==GL_RENDER) {
  520.       if (ctx->NoRaster) {
  521.          ctx->PointsFunc = null_points;
  522.          return;
  523.       }
  524.       if (ctx->Driver.PointsFunc) {
  525.          /* Device driver will draw points. */
  526.          ctx->PointsFunc = ctx->Driver.PointsFunc;
  527.       }
  528.       else if (ctx->Point.SmoothFlag && rgbmode) {
  529.          ctx->PointsFunc = antialiased_rgba_points;
  530.       }
  531.       else if (gl_texturing_enabled(ctx)) {
  532.      ctx->PointsFunc = textured_rgba_points;
  533.       }
  534.       else if (ctx->Point.Size==1.0) {
  535.          /* size=1, any raster ops */
  536.          ctx->PointsFunc = rgbmode ? size1_rgba_points : size1_ci_points;
  537.       }
  538.       else {
  539.      /* every other kind of point rendering */
  540.      ctx->PointsFunc = rgbmode ? general_rgba_points
  541.                                          : general_ci_points;
  542.       }
  543.    }
  544.    else if (ctx->RenderMode==GL_FEEDBACK) {
  545.       ctx->PointsFunc = feedback_points;
  546.    }
  547.    else {
  548.       /* GL_SELECT mode */
  549.       ctx->PointsFunc = select_points;
  550.    }
  551.  
  552. }
  553.  
  554.